MICHAELIS_MENTEN
Overview
The MICHAELIS_MENTEN function numerically solves the Michaelis-Menten system of ordinary differential equations (ODEs) for enzyme kinetics, modeling how substrate concentration changes over time during an enzyme-catalyzed reaction. This implementation uses SciPy’s solve_ivp to integrate the system of differential equations.
Michaelis-Menten kinetics, named after Leonor Michaelis and Maud Menten, is the foundational model in enzyme kinetics. The model describes how an enzyme (E) binds to a substrate (S) to form an enzyme-substrate complex, which then releases a product (P):
E + S \underset{k_{-1}}{\stackrel{k_{+1}}{\rightleftharpoons}} ES \xrightarrow{k_{cat}} E + P
The rate of substrate consumption follows the Michaelis-Menten equation:
v = \frac{dP}{dt} = \frac{k_{cat} \cdot E \cdot S}{K_m + S}
where k_{cat} is the catalytic rate constant (turnover number), representing the maximum number of substrate molecules converted to product per enzyme molecule per unit time. The Michaelis constant K_m equals the substrate concentration at which the reaction rate is half of V_{max}, providing a measure of enzyme-substrate affinity.
This function integrates the ODE system where substrate concentration decreases according to the reaction rate (dS/dt = -v) while enzyme concentration remains constant (dE/dt = 0), reflecting the catalytic nature of enzymes. The function supports multiple numerical integration methods including explicit Runge-Kutta (RK45, RK23, DOP853) for non-stiff problems and implicit methods (Radau, BDF, LSODA) for stiff systems. For more details on the integration methods, see the SciPy solve_ivp documentation.
Michaelis-Menten kinetics has broad applications beyond biochemistry, including pharmacokinetics, blood alcohol clearance, and ecological models such as the Monod equation for microbial growth.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=MICHAELIS_MENTEN(s_initial, e_initial, k_cat, k_m, t_start, t_end, timesteps, mm_method)
s_initial(float, required): Initial substrate concentration.e_initial(float, required): Initial enzyme concentration.k_cat(float, required): Catalytic rate constant (turnover number).k_m(float, required): Michaelis constant.t_start(float, required): Start time for integration.t_end(float, required): End time for integration.timesteps(int, optional, default: 10): Number of timesteps to solve for.mm_method(str, optional, default: “RK45”): Integration method for ODE solver.
Returns (list[list]): 2D list with header [t, S, E], or error message string.
Examples
Example 1: Demo case 1
Inputs:
| s_initial | e_initial | k_cat | k_m | t_start | t_end | timesteps |
|---|---|---|---|---|---|---|
| 10 | 1 | 2 | 1 | 0 | 5 | 10 |
Excel formula:
=MICHAELIS_MENTEN(10, 1, 2, 1, 0, 5, 10)
Expected output:
| t | S | E |
|---|---|---|
| 0 | 10 | 1 |
| 0.5556 | 8.995 | 1 |
| 1.111 | 8.001 | 1 |
| 1.667 | 7.02 | 1 |
| 2.222 | 6.057 | 1 |
| 2.778 | 5.115 | 1 |
| 3.333 | 4.201 | 1 |
| 3.889 | 3.324 | 1 |
| 4.444 | 2.498 | 1 |
| 5 | 1.746 | 1 |
Example 2: Demo case 2
Inputs:
| s_initial | e_initial | k_cat | k_m | t_start | t_end | timesteps | mm_method |
|---|---|---|---|---|---|---|---|
| 5 | 0.5 | 1.5 | 0.5 | 0 | 2 | 10 | RK23 |
Excel formula:
=MICHAELIS_MENTEN(5, 0.5, 1.5, 0.5, 0, 2, 10, "RK23")
Expected output:
| t | S | E |
|---|---|---|
| 0 | 5 | 0.5 |
| 0.2222 | 4.849 | 0.5 |
| 0.4444 | 4.698 | 0.5 |
| 0.6667 | 4.547 | 0.5 |
| 0.8889 | 4.398 | 0.5 |
| 1.111 | 4.248 | 0.5 |
| 1.333 | 4.099 | 0.5 |
| 1.556 | 3.951 | 0.5 |
| 1.778 | 3.803 | 0.5 |
| 2 | 3.656 | 0.5 |
Example 3: Demo case 3
Inputs:
| s_initial | e_initial | k_cat | k_m | t_start | t_end | timesteps | mm_method |
|---|---|---|---|---|---|---|---|
| 8 | 2 | 3 | 2 | 0 | 3 | 10 | RK45 |
Excel formula:
=MICHAELIS_MENTEN(8, 2, 3, 2, 0, 3, 10, "RK45")
Expected output:
| t | S | E |
|---|---|---|
| 0 | 8 | 2 |
| 0.3333 | 6.435 | 2 |
| 0.6667 | 4.957 | 2 |
| 1 | 3.598 | 2 |
| 1.333 | 2.404 | 2 |
| 1.667 | 1.436 | 2 |
| 2 | 0.7457 | 2 |
| 2.333 | 0.3366 | 2 |
| 2.667 | 0.1368 | 2 |
| 3 | 0.05251 | 2 |
Example 4: Demo case 4
Inputs:
| s_initial | e_initial | k_cat | k_m | t_start | t_end | timesteps |
|---|---|---|---|---|---|---|
| 2 | 0.2 | 1 | 0.2 | 0 | 0.5 | 10 |
Excel formula:
=MICHAELIS_MENTEN(2, 0.2, 1, 0.2, 0, 0.5, 10)
Expected output:
| t | S | E |
|---|---|---|
| 0 | 2 | 0.2 |
| 0.05556 | 1.99 | 0.2 |
| 0.1111 | 1.98 | 0.2 |
| 0.1667 | 1.97 | 0.2 |
| 0.2222 | 1.96 | 0.2 |
| 0.2778 | 1.95 | 0.2 |
| 0.3333 | 1.939 | 0.2 |
| 0.3889 | 1.929 | 0.2 |
| 0.4444 | 1.919 | 0.2 |
| 0.5 | 1.909 | 0.2 |
Python Code
from scipy.integrate import solve_ivp as scipy_solve_ivp
import numpy as np
def michaelis_menten(s_initial, e_initial, k_cat, k_m, t_start, t_end, timesteps=10, mm_method='RK45'):
"""
Numerically solves the Michaelis-Menten system of ordinary differential equations for enzyme kinetics using scipy.integrate.solve_ivp.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html
This example function is provided as-is without any representation of accuracy.
Args:
s_initial (float): Initial substrate concentration.
e_initial (float): Initial enzyme concentration.
k_cat (float): Catalytic rate constant (turnover number).
k_m (float): Michaelis constant.
t_start (float): Start time for integration.
t_end (float): End time for integration.
timesteps (int, optional): Number of timesteps to solve for. Default is 10.
mm_method (str, optional): Integration method for ODE solver. Valid options: RK45, RK23, DOP853, Radau, BDF, LSODA. Default is 'RK45'.
Returns:
list[list]: 2D list with header [t, S, E], or error message string.
"""
# Validate inputs
try:
s0 = float(s_initial)
e0 = float(e_initial)
kcat = float(k_cat)
km = float(k_m)
t0 = float(t_start)
t1 = float(t_end)
ntp = int(timesteps)
except Exception:
return "Invalid input: all initial values, parameters, and timesteps must be numbers."
if t1 <= t0:
return "Invalid input: t_end must be greater than t_start."
if ntp <= 0:
return "Invalid input: timesteps must be a positive integer."
if s0 < 0 or e0 < 0 or kcat < 0 or km < 0:
return "Invalid input: concentrations and rate constants must be non-negative."
allowed_methods = ['RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA']
if mm_method not in allowed_methods:
return f"Invalid input: mm_method must be one of {allowed_methods}."
# Create time array for evaluation
t_eval = np.linspace(t0, t1, ntp)
# Michaelis-Menten ODE system: dS/dt = -v, dE/dt = 0
def mm_ode(t, y):
S, E = y
v = (kcat * E * S) / (km + S) if (km + S) != 0 else 0.0
dSdt = -v
dEdt = 0.0
return [dSdt, dEdt]
try:
sol = scipy_solve_ivp(
mm_ode,
[t0, t1],
[s0, e0],
method=mm_method,
dense_output=False,
t_eval=t_eval,
rtol=1e-6,
atol=1e-8
)
except Exception as e:
return f"ODE integration error: {e}"
if not sol.success:
return f"ODE integration failed: {sol.message}"
# Prepare output: header row then data rows
result = [["t", "S", "E"]]
for i in range(len(sol.t)):
t_val = float(sol.t[i])
s_val = float(sol.y[0][i])
e_val = float(sol.y[1][i])
# Check for nan/inf values
if not (np.isfinite(t_val) and np.isfinite(s_val) and np.isfinite(e_val)):
return "Invalid output: nan or inf detected."
result.append([t_val, s_val, e_val])
return result